using System;
using System.Data;
using NHibernate;
using Castle.Core.Logging;
using Caramel;

namespace Caramel.NHibernate
{
	public class NHibernateReadOnlyUnitOfWork : IUnitOfWork, INHibernateUnitOfWork
	{
		//private bool _wasCommitted = false;
		//private bool _wasRolledBack = false;
		private bool _isDisposed = false;
		private ISession _session;
		//private ITransaction _transaction;

		public NHibernateReadOnlyUnitOfWork(ISession session, string name, IsolationLevel isolationLevel)
		{
			this.Logger = NullLogger.Instance;
			this.Name = name;
			this.ID = Guid.NewGuid();
			this.Session = session;
			//_transaction = this.Session.BeginTransaction(isolationLevel);
		}

		public Castle.Core.Logging.ILogger Logger { get; set; }

		#region INHibernateUnitOfWork Members

		public ISession Session
		{
			get
			{
				this.EnsureNotDisposed();

				return _session;
			}
			private set
			{
				_session = value;
			}
		}

		#endregion

		#region IUnitOfWork Members

		public string Name { get; private set; }

		public Guid ID { get; private set; }

		public bool WasCommitted { get; private set; }

		public bool WasRolledBack { get; private set; }

		public void Commit()
		{
			this.EnsureNotDisposed();

			throw new NotSupportedException("");
		}

		public void Rollback()
		{
			this.EnsureNotDisposed();

			throw new NotSupportedException("");
		}

		public void Evict(object entity)
		{
			this.EnsureNotDisposed();

			throw new NotSupportedException("");
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if (!_isDisposed)
			{
				//if (_transaction.IsActive)
				//{
				//    _session.Clear();
				//    _transaction.Commit();
				//}

				//_transaction = null;
				this.Session.Dispose();
				this.Session = null;

				UnitOfWork.DisposeOfUnitOfWork(this);

				_isDisposed = true;
			}
		}

		#endregion

		//private void EnsureIsActive()
		//{
		//    this.EnsureWasNotCommitted();
		//    this.EnsureWasNotRolledBack();
		//    this.EnsureNotDisposed();
		//}

		//private void EnsureWasNotCommitted()
		//{
		//    if (this.WasCommitted)
		//    {
		//        throw new InvalidOperationException("Work was already committed.");
		//    }
		//}

		//private void EnsureWasNotRolledBack()
		//{
		//    if (this.WasRolledBack)
		//    {
		//        throw new InvalidOperationException("Work was already committed.");
		//    }
		//}

		private void EnsureNotDisposed()
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}
		}
	}
}
